<template>
	<a-flex wrap="wrap" gap="small">
		<div
			class="model-container"
			v-for="(model, index) in modelArray"
			:key="model.id"
			@mouseover="onMouseEnter(index)"
			@mouseleave="onMouseLeave(index)"
		>
			<span class="model-delete">
				<CloseCircleFilled
					:class="index === deleteShow ? 'show-delete-icon' : ''"
					class="delete-icon"
					@click="deleteModel(model)"
				/>
				<div class="container">
					<a-tag :color="model.color" class="container-tag">
						<component :is="model.icon" class="container-tag-icon" />
					</a-tag>
					<span class="container-span">{{ model.label }}</span>
				</div>
			</span>
			<span class="model-name">{{ model.name }}</span>
		</div>
		<a-button
			shape="circle"
			@click="openModal"
			style="border-radius: 2px"
			v-if="props.radioModel ? modelArray.length !== 1 : true"
		>
			<PlusOutlined />
		</a-button>
		<slot name="button"></slot>
	</a-flex>
	<a-modal
		v-model:open="visible"
		title="流程选择"
		:width="800"
		:mask-closable="false"
		:destroy-on-close="true"
		@ok="handleOk"
		@cancel="handleClose"
	>
		<a-row :gutter="10">
			<a-col :span="6">
				<a-card size="small" :loading="cardLoading" class="selectorTreeDiv">
					<a-tree v-if="treeData" :tree-data="treeData" :field-names="treeFieldNames" @select="treeSelect" />
				</a-card>
			</a-col>
			<a-col :span="12">
				<div class="table-operator xn-mb10">
					<a-form ref="searchFormRef" name="advanced_search" class="ant-advanced-search-form" :model="searchFormState">
						<a-row :gutter="24">
							<a-col :span="12">
								<a-form-item name="searchKey">
									<a-input v-model:value="searchFormState.searchKey" placeholder="请输入用户名" />
								</a-form-item>
							</a-col>
							<a-col :span="12">
								<a-button type="primary" class="xn-mr-10" @click="loadData()"> 查询 </a-button>
								<a-button @click="reset()"> 重置 </a-button>
							</a-col>
						</a-row>
					</a-form>
				</div>
				<div class="selector-table">
					<a-table size="small" :columns="commons" bordered :data-source="tableData" :loading="pageLoading">
						<template #title>
							<span>待选择列表 {{ tableRecordNum }} 条</span>
							<div v-if="!radioModel" class="xn-fdr">
								<a-button type="dashed" size="small" @click="addAllPageRecord">添加当前数据</a-button>
							</div>
						</template>
						<template #bodyCell="{ column, record }">
							<template v-if="column.dataIndex === 'icon'">
								<a-tag :color="record.color">
									<component :is="record.icon" />
								</a-tag>
							</template>
							<template v-if="column.dataIndex === 'category'">
								{{ $TOOL.dictTypeData('MODEL_CATEGORY', record.category) }}
							</template>
							<template v-if="column.dataIndex === 'action'">
								<a-button type="dashed" size="small" @click="addRecord(record)"><PlusOutlined /></a-button>
							</template>
						</template>
					</a-table>
				</div>
			</a-col>
			<a-col :span="6">
				<div class="selector-table">
					<a-table
						ref="selectedTable"
						size="small"
						:columns="selectedCommons"
						:data-source="selectedData"
						:expand-row-by-click="true"
						:loading="selectedTableListLoading"
						bordered
					>
						<template #title>
							<span>已选择: {{ selectedData.length }}</span>
							<div v-if="!radioModel" class="xn-fdr">
								<a-button type="dashed" danger size="small" @click="delAllRecord">全部移除</a-button>
							</div>
						</template>
						<template #bodyCell="{ column, record }">
							<template v-if="column.dataIndex === 'action'">
								<a-button type="dashed" danger size="small" @click="delRecord(record)"><MinusOutlined /></a-button>
							</template>
						</template>
					</a-table>
				</div>
			</a-col>
		</a-row>
	</a-modal>
</template>

<script setup name="modelSelector">
	import { message } from 'ant-design-vue'
	import { remove, isEmpty, cloneDeep } from 'lodash-es'
	import tool from '@/utils/tool'
	const modelArray = ref([])
	const deleteShow = ref('')
	const visible = ref(false)
	const tableData = ref([])
	const treeFieldNames = { children: 'children', title: 'label', key: 'value' }
	const cardLoading = ref(false)
	const treeData = tool.dictList('MODEL_CATEGORY')
	const searchFormState = ref({})
	const searchFormRef = ref()
	const selectedTable = ref()
	const selectedData = ref([])
	const recordIds = ref([])
	const selectedTableListLoading = ref(false)
	const tableRecordNum = ref()
	const pageLoading = ref(false)
	// 分页相关
	const current = ref(0) // 当前页数
	const pageSize = ref(20) // 每页条数
	const total = ref(0) // 数据总数
	const props = defineProps({
		radioModel: {
			type: Boolean,
			default: () => false
		},
		modelPageApi: {
			type: Function
		},
		value: {
			type: Array,
			default: () => []
		},
		dataType: {
			type: String,
			default: () => 'string'
		},
		userShow: {
			type: Boolean,
			default: () => true
		},
		addShow: {
			type: Boolean,
			default: () => true
		}
	})
	const emit = defineEmits(['update:value', 'onBack'])
	const commons = [
		{
			title: '操作',
			dataIndex: 'action',
			align: 'center',
			width: 50
		},
		{
			title: '图标',
			dataIndex: 'icon',
			width: 50
		},
		{
			title: '名称',
			dataIndex: 'name',
			ellipsis: true
		}
	]
	// 选中表格的表格common
	const selectedCommons = [
		{
			title: '操作',
			dataIndex: 'action',
			align: 'center',
			width: 50
		},
		{
			title: '名称',
			dataIndex: 'name',
			ellipsis: true
		}
	]
	watch(
		() => props.value,
		(newValue) => {
			if (!isEmpty(props.value)) {
				modelArray.value = newValue
				selectedData.value = newValue
			}
		},
		{
			immediate: true // 立即执行
		}
	)
	const onMouseEnter = (index) => {
		deleteShow.value = index
	}
	const onMouseLeave = () => {
		deleteShow.value = ''
	}
	// 点击删除模型
	const deleteModel = (model) => {
		// 删除显示的
		remove(modelArray.value, (item) => item.id === model.id)
		// 删除缓存的
		remove(selectedData.value, (item) => item.id === model.id)
		const value = []
		const showModel = []
		modelArray.value.forEach((item) => {
			const obj = {
				id: item.id,
				name: item.name,
				icon: item.icon,
				color: item.color,
				iconMobile: item.iconMobile
			}
			value.push(item.id)
			// 拷贝一份obj数据
			const objClone = cloneDeep(obj)
			showModel.push(objClone)
		})
		modelArray.value = showModel
		emit('update:value', showModel)
		emit('onBack', showModel)
	}
	const openModal = () => {
		if (typeof props.modelPageApi !== 'function') {
			message.warning('未配置选择器需要的modelPageApi接口')
			return
		}
		visible.value = true
		searchFormState.value.size = pageSize.value
		loadData()
	}
	const handleOk = () => {
		modelArray.value = []
		const value = []
		const showModel = []
		selectedData.value.forEach((item) => {
			const obj = {
				id: item.id,
				name: item.name,
				icon: item.icon,
				color: item.color,
				iconMobile: item.iconMobile
			}
			value.push(item.id)
			// 拷贝一份obj数据
			const objClone = cloneDeep(obj)
			showModel.push(objClone)
		})
		modelArray.value = showModel
		emit('update:value', showModel)
		emit('onBack', showModel)
		handleClose()
	}
	const handleClose = () => {
		searchFormState.value = {}
		tableRecordNum.value = 0
		tableData.value = []
		current.value = 0
		pageSize.value = 20
		total.value = 0
		visible.value = false
	}
	const loadData = () => {
		pageLoading.value = true
		props
			.modelPageApi(searchFormState.value)
			.then((data) => {
				current.value = data.current
				// pageSize.value = data.size
				total.value = data.total
				// 重置、赋值
				tableData.value = []
				tableRecordNum.value = 0
				// 数据非分页写法
				// tableData.value = data
				// if (data) {
				// 	tableRecordNum.value = data.length
				// } else {
				// 	tableRecordNum.value = 0
				// }
				// 如果换成分页，这里做改动即可
				tableData.value = data.records
				if (data.records) {
					tableRecordNum.value = data.records.length
				} else {
					tableRecordNum.value = 0
				}
			})
			.finally(() => {
				pageLoading.value = false
			})
	}
	const reset = () => {
		delete searchFormState.value.searchKey
		loadData()
	}
	const judge = () => {
		return !(props.radioModel && selectedData.value.length > 0)
	}
	// 添加记录
	const addRecord = (record) => {
		if (!judge()) {
			message.warning('只可选择一条')
			return
		}
		const selectedRecord = selectedData.value.filter((item) => item.id === record.id)
		if (selectedRecord.length === 0) {
			selectedData.value.push(record)
		} else {
			message.warning('该记录已存在')
		}
	}
	// 添加全部
	const addAllPageRecord = () => {
		let newArray = selectedData.value.concat(tableData.value)
		let list = []
		for (let item1 of newArray) {
			let flag = true
			for (let item2 of list) {
				if (item1.id === item2.id) {
					flag = false
				}
			}
			if (flag) {
				list.push(item1)
			}
		}
		selectedData.value = list
	}
	// 点击树查询
	const treeSelect = (selectedKeys) => {
		if (selectedKeys.length > 0) {
			searchFormState.value.category = selectedKeys.toString()
		} else {
			delete searchFormState.value.category
		}
		loadData()
	}
	// 删减记录
	const delRecord = (record) => {
		remove(selectedData.value, (item) => item.id === record.id)
	}
	// 删减记录
	const delAllRecord = () => {
		selectedData.value = []
	}
</script>

<style scoped lang="less">
	.model-container {
		display: flex;
		align-items: center; /* 垂直居中 */
		flex-direction: column;
		text-align: center;
	}
	.delete-icon {
		position: absolute;
		right: -2px;
		z-index: 5;
		top: -3px;
		cursor: pointer;
		visibility: hidden;
	}
	.xn-mr-10 {
		margin-right: 10px;
	}
	.selector-table {
		overflow: auto;
		max-height: 450px;
	}
	.ant-form-item {
		margin-bottom: 0 !important;
	}
	.delete-icon {
		position: absolute;
		right: -2px;
		z-index: 5;
		top: -3px;
		cursor: pointer;
		visibility: hidden;
	}
	.show-delete-icon {
		visibility: visible;
	}
	.model-delete {
		z-index: 99;
		color: rgba(0, 0, 0, 0.25);
		position: relative;
		display: flex;
		flex-direction: column;
	}
	.model-name {
		font-size: 12px;
		max-width: 50px;
		white-space: nowrap;
		overflow: hidden;
	}

	.container {
		border-radius: 5px;
		display: flex;
		align-items: center;
		cursor: pointer;
	}
	.container-tag {
		width: 32px;
		height: 32px;
		border-radius: 2px;
		display: flex;
		align-items: center;
		margin-left: 10px;
	}
	.container-tag-icon {
		font-size: 16px;
	}
	.container-span {
		max-width: 60%;
		font-weight: 500;
	}
</style>
